﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;


namespace monitor_client
{
    public delegate void f2close();
    public delegate void fstart();
    

    public partial class AuthentificationForm : Form
    {
        MainForm form2;
        System.Windows.Forms.Timer conTimer;
        const string version_str = "1.0";                       //Версия клиента
        /*static IPAddress ip = System.Net.IPAddress.Parse("127.0.0.1");
        IPEndPoint remoteEP = new IPEndPoint(ip, 38802);
        Socket send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);*/
        IPEndPoint remoteEP;
        IPAddress ip;
        Socket send;
        private byte[] cc = { 0x63 };

        private bool IsOpened { get; set; }

        public AuthentificationForm()
        {
            InitializeComponent();
            toolStripStatusLabel1.Text = "Установка связи с сервером...";
            //toolStripStatusLabel1.Text = "Связь с сервером установлена";
            toolStripStatusLabel1.Visible = true;
            this.IsOpened = true;
            if (!File.Exists(@"resources\server"))
            {
                ServerAddressForm form3 = new ServerAddressForm(new fstart(fstart));
                form3.Owner = this;
                form3.Show();
                this.Enabled = false;
            }
            else
            {
                string serverIP = File.ReadAllText(@"resources\server");
                CurServIPTextBox.Text = serverIP;
            }
        }

        void form2close()
        {
            send.Close();
            if(File.Exists(@"resources\selzone.ini"))
                File.Delete(@"resources\selzone.ini");
            if (File.Exists(@"resources\brest.ini"))
                File.Delete(@"resources\brest.ini");
            if (File.Exists(@"resources\gomel.ini"))
                File.Delete(@"resources\gomel.ini");
            if (File.Exists(@"resources\minsk.ini"))
                File.Delete(@"resources\minsk.ini");
            if (File.Exists(@"resources\mogil.ini"))
                File.Delete(@"resources\mogil.ini");
            if (File.Exists(@"resources\viteb.ini"))
                File.Delete(@"resources\viteb.ini");
            if (File.Exists(@"resources\grodn.ini"))
                File.Delete(@"resources\grodn.ini");
            //if (File.Exists(@"resources\adresses_temp.ini"))
                //File.Delete(@"resources\adresses_temp.ini");
            //Close();
            try
            {
                form2.Close();
            }
            catch (NullReferenceException)
            { }
            //Application.Exit();
        }

        void fstart()
        {
            send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            send.SendTimeout = 5;
            send.ReceiveTimeout = 5;
            ip = System.Net.IPAddress.Parse(File.ReadAllText(@"resources\server"));
            CurServIPTextBox.Text = ip.ToString();
            remoteEP = new IPEndPoint(ip, 38802);
            try
            {
                send.Connect(remoteEP);
                DBOperations.Sock = send;
                toolStripStatusLabel1.Text = "Связь с сервером установлена";
            }
            catch (SocketException)
            {
                MessageBox.Show("Нет связи с сервером.\r\nПроверьте адрес сервера либо удостоверьтесь, что сервер активен.");
                toolStripStatusLabel1.Text = "Установка связи с сервером...";
                send.Close();
                //this.Close();
            }
            this.Enabled = true;
        }

        private int find_divider(int i, byte[] mes)
        {
            while (true)
            {
                if (mes[i] == (byte)';' && mes[i + 1] == (byte)'.' && mes[i + 2] == (byte)';' && mes[i + 3] == (byte)';')
                {
                    i = i + 4;
                    break;
                }
                i++;
            }
            return i;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            int k = DBOperations.RetreiveServerIP();
            switch (k)
            {
                case 2:
                    MessageBox.Show("Адрес сервера не указан!");
                    ServerAddressForm form3 = new ServerAddressForm(new fstart(fstart));
                    form3.Owner = this;
                    form3.Show();
                    this.Enabled = false;
                    break;
                case 3:
                    MessageBox.Show("Файл 'resources\\server' не доступен для чтения.");
                    break;
            }
            rec_options options = new rec_options();
            int count = 0;
            int bytesrec = 0;
            toolStripStatusLabel1.Text = "Установка связи с сервером...";
            byte[] version = new byte[version_str.Length];
            version = Encoding.ASCII.GetBytes(version_str);
            string rec = "";
            toolStripStatusLabel1.Text = "Отправка запроса доступа в сеть...";
            System.IO.StringReader read = new System.IO.StringReader(textBox1.Text);
            string log = read.ReadToEnd();
            read = new System.IO.StringReader(textBox2.Text);
            string pass = read.ReadToEnd();
            read.Close();
            byte lv = (byte)version.Length;
            byte ll = (byte)log.Length;
            byte lp = (byte)pass.Length;
            byte[] reply = new byte[600];
            byte[] message = new byte[version.Length + log.Length + pass.Length + 3];
            message[0] = lv;
            message[lv + 1] = ll;
            message[ll + lv + 2] = lp;
            for (int i = 1; i <= lv; i++)
            {
                message[i] = version[i - 1];
            }
            for (int i = lv + 2; i <= lv + ll + 1; i++)
            {
                message[i] = (byte)log[i - lv - 2];
            }
            for (int i = lv + ll + 3; i <= lv + ll + lp + 2; i++)
            {
                message[i] = (byte)pass[i - lv - ll - 3];
            }
            if (!send.Connected)
            {
                send.Close();
                send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                send.SendTimeout = 1000;
                send.ReceiveTimeout = 1000;
                try
                {
                    send.Connect(remoteEP);
                    DBOperations.Sock = send;
                }
                catch (SocketException)
                {
                    MessageBox.Show("Нет связи с сервером!");
                    toolStripStatusLabel1.Text = "Связь с сервером потеряна";
                    return;
                }
            }
            

            while (count < 3)
            {
                try
                {
                    byte[] mesLen = new byte[4];
                    send.Send(message);
                    send.Receive(mesLen);
                    //Принимаем размер массива для определения размера буфера
                    reply = new byte[BitConverter.ToInt32(mesLen, 0)];
                    //Получение ответа от сервера
                    bytesrec = send.Receive(reply);
                    rec = Encoding.ASCII.GetString(reply, 0, 10);
                    //Определение режима доступа
                    switch (rec)
                    {
                        case "admiaccess":
                            options.access = 1;
                            break;
                        case "useraccess":
                            options.access = 2;
                            break;
                        case "accessden1":
                            options.access = 3;
                            break;
                        case "accessden2":
                            options.access = 4;
                            break;
                        case "accessden3":
                            options.access = 5;
                            break;
                        default:
                            MessageBox.Show("Неудачная попытка установки связи.");
                            toolStripStatusLabel1.Text = "Связь с сервером потеряна";
                            return;
                    }
                    if (options.access < 3)
                    {
                        //options.oblast[0] = Encoding.Default.GetString(reply, 10, 5);

                            //Все области
                        //if (options.oblast[0] == "minsk")
                        //{
                        string[] obls = Encoding.Default.GetString(reply, 10, reply.Length - 10).Split(';');
                        options.oblast = new string[obls.Length - 1];
                        for (int j = 0; j < obls.Length - 1; j++)
                        {
                            string[] split = obls[j].Split(':');
                            options.oblast[j] = split[0];
                            File.WriteAllBytes(@"resources\\" + split[0] + ".ini", Encoding.Default.GetBytes(split[1]));
                        }
                        //}

                            //Только одна область
                        /*else
                        {
                            i = 16;
                            i = find_divider(i, reply);
                            i = i - 20;
                            recb = new byte[i];
                            for (int u = 0; u < i; u++)
                            {
                                recb[u] = reply[16 + u];
                            }

                            File.WriteAllBytes(@"resources\\" + options.oblast[0].Substring(0) + ".ini", recb);
                        }*/
                    }
                    
                }
                catch (SocketException)
                {
                    if (!send.Connected)
                    {
                        send.Close();
                        send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        send.SendTimeout = 5;
                        send.ReceiveTimeout = 5;
                        send.Connect(remoteEP);
                    }
                }
                if (bytesrec != 0)
                    break;
                else
                    count++;
            }
            count = 0;
            /*
            rec = Encoding.ASCII.GetString(messagerec, 0, 10);
            
            switch (rec)
            {
                case "admiaccess":
                    options.access = 1;                    
                    break;
                case "useraccess":
                    options.access = 2;
                    break;
                case "accessden1":
                    options.access = 3;
                    break;
                case "accessden2":
                    options.access = 4;
                    break;
                default:
                    MessageBox.Show("Неудачная попытка установки связи.");
                    toolStripStatusLabel1.Text = "Связь с сервером потеряна";
                    return;
            }*/
            switch (options.access)
            {
                case 1:
                case 2:
                    this.Hide();
                    this.IsOpened = false;
                    form2 = new MainForm(form2close, options);
                    form2.Owner = this;
                    form2.Enabled = true;
                    form2.Show();                    
                    break;
                case 3:
                    MessageBox.Show("Неправильное имя пользователя или пароль.");
                    toolStripStatusLabel1.Text = "Связь с сервером установлена";
                    break;
                case 4:
                    MessageBox.Show("Несоответствие версий.");
                    toolStripStatusLabel1.Text = "Связь с сервером установлена";
                    break;
                case 5:
                    MessageBox.Show("Ваш IP-адрес отсутствует в списке доверенных.");
                    toolStripStatusLabel1.Text = "Связь с сервером установлена";
                    break;
            }
            
        }

        private void button2_Click(object sender, EventArgs e)
        {
            send.Close();
            //Close();
            Application.Exit();
        }

        private void timtick(Object myObject, EventArgs myEventArgs)
        {
            byte[] get = new byte[1];
            int  i = 3;
            conTimer.Stop();
            
            while(i-- > 0)
            {
                try
                {
                    if (!send.Connected)
                    {
                        send.Close();
                        toolStripStatusLabel1.Text = "Установка связи с сервером...";
                        send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                        send.SendTimeout = 5;
                        send.ReceiveTimeout = 5;
                        send.Connect(remoteEP);
                    }
                    send.Send(cc);
                    send.Receive(get);
                    toolStripStatusLabel1.Text = "Связь с сервером установлена";
                }
                catch (SocketException)
                {
                    if (i == 0)
                    {
                        if (!this.IsOpened)
                        {
                            MessageBox.Show("Связь с сервером потеряна.\r\nПрограмма будет закрыта.");                        
                            form2close();
                            this.IsOpened = true;
                        }
                    }
                }
                catch (ObjectDisposedException)
                {
                    if (!this.IsOpened)
                    {
                        MessageBox.Show("Связь с сервером потеряна.\r\nПрограмма будет закрыта.");
                        form2close();
                        this.IsOpened = true;
                    }
                }
            }
            conTimer.Start();
        }

        private void StartTimer()
        {
            conTimer = new System.Windows.Forms.Timer();
            conTimer.Interval = 5000;
            conTimer.Enabled = true;
            conTimer.Start();
            conTimer.Tick += new EventHandler(timtick);
        }

        private void StopTimer()
        {
            conTimer.Stop();
            conTimer.Dispose();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            if (!File.Exists(@"resources\server"))
            {
                ServerAddressForm form3 = new ServerAddressForm(new fstart(fstart));
                form3.Owner = this;
                form3.Show();
                this.Enabled = false;                
            }
            else
            {
                send = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                send.SendTimeout = 5;
                send.ReceiveTimeout = 5;
                ip = System.Net.IPAddress.Parse(File.ReadAllText(@"resources\server"));
                remoteEP = new IPEndPoint(ip, 38802);
                try
                {
                    send.Connect(remoteEP);
                    DBOperations.Sock = send;
                    toolStripStatusLabel1.Text = "Установка связи с сервером...";
                }
                catch (SocketException)
                {
                    //MessageBox.Show("Нет связи с сервером.\r\nПрограмма будет закрыта.");
                    send.Close();
                    //this.Close();
                }
                StartTimer();
            }
        }

        private void ChangeServerButton_Click(object sender, EventArgs e)
        {
            ServerAddressForm form3 = new ServerAddressForm(new fstart(fstart));
            form3.Owner = this;
            form3.Show();
            this.Enabled = false;
            string serverIP = File.ReadAllText(@"resources\server");
            CurServIPTextBox.Text = serverIP;
        }

        private void AuthentificationForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            send.Close();
            Application.Exit();
        }
    }

    public class rec_options
    {
        /// <summary>
        /// 1 - Admin; 
        /// 2 - User; 
        /// 3 - login denied; 
        /// 4 - version is not correct;
        /// 5 - unknown ip;
        /// </summary>
        public int access;
        public TreeNode[] devices;
        public string[] oblast = new string[6];
    }
}